package org.yu.team2023.flashdays;

import com.google.common.collect.Maps;

import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;

import java.util.Map;

import static org.yu.team2023.flashdays.ModAttributes.*;

public class TreasurePools {
    public static class Main {
        private static final Map<String, MainTreasure> TREASURE_MAP = Maps.newConcurrentMap();
        public static final MainTreasure EMPTY;
        public static final MainTreasure HEALTH;
        public static final MainTreasure DAMAGE;
        public static final MainTreasure CRIT;
        public static final MainTreasure CRIT_EFFECT;


        static {
            register(EMPTY = new MainTreasure(() -> Attributes.JUMP_STRENGTH, "empty", 0, 0, AttributeModifier.Operation.ADDITION));
            register(CRIT = new MainTreasure(ModAttributes.CRIT, "crit", 8.8, 3.3, AttributeModifier.Operation.ADDITION));
            register(CRIT_EFFECT = new MainTreasure(ModAttributes.CRIT_EFFECT, "crit_effect", 17.6, 6.6, AttributeModifier.Operation.ADDITION));
            register(HEALTH = new MainTreasure(() -> Attributes.MAX_HEALTH, "max_health", 4, 1, AttributeModifier.Operation.ADDITION));
            register(new MainTreasure(() -> Attributes.MAX_HEALTH, "max_health_multi", 0.09, 0.05, AttributeModifier.Operation.MULTIPLY_BASE));
            register(DAMAGE = new MainTreasure(() -> Attributes.ATTACK_DAMAGE, "attack_damage", 2, 0.5, AttributeModifier.Operation.ADDITION));
            register(new MainTreasure(() -> Attributes.ATTACK_DAMAGE, "attack_damage_multi", 0.035, 0.025, AttributeModifier.Operation.MULTIPLY_BASE));
            register(new MainTreasure(() -> Attributes.MOVEMENT_SPEED, "move_speed_multi", 0.035, 0.025, AttributeModifier.Operation.MULTIPLY_BASE));
            register(new MainTreasure(HEALTH_STEAL, "health_steal", 4.6, 2, AttributeModifier.Operation.ADDITION));
            register(new MainTreasure(RECOVER_EFFECT, "recover_effect", 9.2, 4, AttributeModifier.Operation.ADDITION));
            register(new MainTreasure(ModAttributes.WEAKNESS_SPECIAL_ATTACK, "weakness_special_attack", 6, 3, AttributeModifier.Operation.ADDITION));
            register(new MainTreasure(ModAttributes.RANGED_DAMAGE, "ranged_damage", 10, 3, AttributeModifier.Operation.ADDITION));
        }

        public static void register(MainTreasure treasure) {
            TREASURE_MAP.put(treasure.getId(), treasure);
        }

        public static MainTreasure role(int index) {
            return switch (index) {
                case 1 -> HEALTH;
                case 2 -> DAMAGE;
                case 3 -> ModUtil.randomSelect(TREASURE_MAP.values().stream().filter(treasure -> treasure != EMPTY && treasure != HEALTH && treasure != DAMAGE).toList());
                default -> ModUtil.randomSelect(TREASURE_MAP.values().stream().filter(treasure -> treasure != EMPTY && treasure != HEALTH && treasure != DAMAGE && treasure != CRIT && treasure != CRIT_EFFECT).toList());
            };
        }

        public static MainTreasure getOrEmpty(String id) {
            return TREASURE_MAP.getOrDefault(id, EMPTY);
        }
    }

    public static class Addition {
        private static final Map<String, AdditionTreasure> TREASURE_MAP = Maps.newConcurrentMap();
        public static final AdditionTreasure EMPTY;

        static {
            register(EMPTY = new AdditionTreasure(() -> Attributes.JUMP_STRENGTH, "empty", 0, 0, 0, 0, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(CRIT, "crit", 2.3, 5.1, 2.3, 5.1, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(CRIT, "crit_effect", 4.6, 10.2, 8.6, 12.1, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(() -> Attributes.MAX_HEALTH, "max_health", 1, 3, 1, 4, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(() -> Attributes.MAX_HEALTH, "max_health_multi", 0.05, 0.1, 0.03, 0.06, AttributeModifier.Operation.MULTIPLY_BASE));
            register(new AdditionTreasure(() -> Attributes.ATTACK_DAMAGE, "attack_damage", 0.5, 1.5, 1, 2, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(() -> Attributes.ATTACK_DAMAGE, "attack_damage_multi", 0.05, 0.1, 0.03, 0.06, AttributeModifier.Operation.MULTIPLY_BASE));
            register(new AdditionTreasure(() -> Attributes.MOVEMENT_SPEED, "move_speed_multi", 0.035, 0.045, 0.035, 0.045, AttributeModifier.Operation.MULTIPLY_BASE));
            register(new AdditionTreasure(HEALTH_STEAL, "health_steal", 3.2, 7.6, 4.6, 5.7, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(RECOVER_EFFECT, "recover_effect", 8, 12, 8, 14, AttributeModifier.Operation.ADDITION));
             register(new AdditionTreasure(ModAttributes.RANGED_DAMAGE, "ranged_damage", 5, 10, 6, 12, AttributeModifier.Operation.ADDITION));
            register(new AdditionTreasure(ModAttributes.DAMAGE_RESISTANCE, "damage_resistance", 3.6, 5, 4, 6, AttributeModifier.Operation.ADDITION));
        }

        public static int size() {
            return TREASURE_MAP.size();
        }

        public static void register(AdditionTreasure treasure) {
            TREASURE_MAP.put(treasure.getId(), treasure);
        }

        public static AdditionTreasure role() {
            return ModUtil.randomSelect(TREASURE_MAP.values().stream().filter(treasure -> treasure != EMPTY).toList());
        }

        public static AdditionTreasure getOrEmpty(String id) {
            return TREASURE_MAP.getOrDefault(id, EMPTY);
        }
    }
}
